package com.jd.jim.client.service.impl;

import com.alibaba.fastjson.JSON;
import com.jd.jim.client.config.AppConfiguration;
import com.jd.jim.client.service.EchoService;
import com.jd.jim.client.service.RouteRequest;
import com.jd.jim.client.thread.ContextHolder;
import com.jd.jim.client.vo.req.GroupReqVO;
import com.jd.jim.client.vo.req.LoginReqVO;
import com.jd.jim.client.vo.req.P2PReqVO;
import com.jd.jim.client.vo.res.OnlineUsersResVO;
import com.jd.jim.client.vo.res.JIMServerResVO;
import com.jd.jim.common.core.proxy.ProxyManager;
import com.jd.jim.common.enums.StatusEnum;
import com.jd.jim.common.exception.JIMException;
import com.jd.jim.common.res.BaseResponse;
import com.jd.jim.gateway.api.RouteApi;
import com.jd.jim.gateway.api.vo.req.ChatReqVO;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author ：sizegang
 * @description：
 * @version: 1.0
 */
@Service
@Slf4j
public class RouteRequestImpl implements RouteRequest {


    @Autowired
    private OkHttpClient okHttpClient;

    @Value("${jim.gateway.url}")
    private String gatewayUrl;

    @Autowired
    private EchoService echoService;


    @Autowired
    private AppConfiguration appConfiguration;

    @Override
    public void sendGroupMsg(GroupReqVO groupReqVO) throws Exception {
        // 获取路由转发
        RouteApi routeApi = new ProxyManager<>(RouteApi.class, gatewayUrl, okHttpClient).getInstance();
        ChatReqVO chatReqVO = new ChatReqVO(groupReqVO.getUserId(), groupReqVO.getMsg());
        Response response = null;
        try {
            response = (Response) routeApi.groupRoute(chatReqVO);
        } catch (Exception e) {
            log.error("exception", e);
        } finally {
            response.body().close();
        }
    }

    @Override
    public void sendP2PMsg(P2PReqVO p2PReqVO) throws Exception {
        // 使用动态代理，可以思考这里为什么要使用动态代理？？？  dubbo核心服务中 dubbo-rpc 中这里是怎么实现的？？？
        RouteApi routeApi = new ProxyManager<>(RouteApi.class, gatewayUrl, okHttpClient).getInstance();
        // 构建请求Vo
        com.jd.jim.gateway.api.vo.req.P2PReqVO vo = new com.jd.jim.gateway.api.vo.req.P2PReqVO();
        vo.setMsg(p2PReqVO.getMsg());
        vo.setReceiveUserId(p2PReqVO.getReceiveUserId());
        vo.setUserId(p2PReqVO.getUserId());

        Response response = null;
        try {
            // 直接调用了一个接口 就实现了一个远程调用了 这是为什么？
            response = (Response) routeApi.p2pRoute(vo);
            String json = response.body().string();
            BaseResponse baseResponse = JSON.parseObject(json, BaseResponse.class);

            // account offline.
            if (baseResponse.getCode().equals(StatusEnum.OFF_LINE.getCode())) {
                log.error(p2PReqVO.getReceiveUserId() + ":" + StatusEnum.OFF_LINE.getMessage());
            }

        } catch (Exception e) {
            log.error("exception", e);
        } finally {
            response.body().close();
        }
    }

    /**
     * 获取IM server
     *
     * @param loginReqVO
     * @return
     * @throws Exception
     */
    @Override
    public JIMServerResVO.ServerInfo getTIMServer(LoginReqVO loginReqVO) throws Exception {
        // 动态代理
        RouteApi routeApi = new ProxyManager<>(RouteApi.class, gatewayUrl, okHttpClient).getInstance();
        com.jd.jim.gateway.api.vo.req.LoginReqVO vo = new com.jd.jim.gateway.api.vo.req.LoginReqVO();
        vo.setUserId(loginReqVO.getUserId());
        vo.setUserName(loginReqVO.getUserName());

        Response response = null;
        JIMServerResVO JIMServerResVO = null;
        try {
            // todo  去 gateway中 登录 负载均衡获取 netty server 这里为了方便 从配置文件BeanConfig 中读取 负载均衡算法 使用反射
            response = (Response) routeApi.login(vo);
            String json = response.body().string();
            JIMServerResVO = JSON.parseObject(json, JIMServerResVO.class);

            //重复失败
            if (!JIMServerResVO.getCode().equals(StatusEnum.SUCCESS.getCode())) {
                echoService.echo(JIMServerResVO.getMessage());

                // when client in reConnect state, could not exit.
                if (ContextHolder.getReconnect()) {
//                    echoService.echo("###{}###", StatusEnum.RECONNECT_FAIL.getMessage());
                    log.error("###{}###", StatusEnum.RECONNECT_FAIL.getMessage());
//                    throw new JIMException(StatusEnum.RECONNECT_FAIL);
                    return JIMServerResVO.getDataBody();
                }

                System.exit(-1);
            }

        } catch (Exception e) {
            log.error("exception", e);
        } finally {
            response.body().close();
        }

        return JIMServerResVO.getDataBody();
    }

    @Override
    public List<OnlineUsersResVO.DataBodyBean> onlineUsers() throws Exception {
        RouteApi routeApi = new ProxyManager<>(RouteApi.class, gatewayUrl, okHttpClient).getInstance();

        Response response = null;
        OnlineUsersResVO onlineUsersResVO = null;
        try {
            response = (Response) routeApi.onlineUser();
            String json = response.body().string();
            onlineUsersResVO = JSON.parseObject(json, OnlineUsersResVO.class);

        } catch (Exception e) {
            log.error("exception", e);
        } finally {
            response.body().close();
        }

        return onlineUsersResVO.getDataBody();
    }

    @Override
    public void offLine() {
        RouteApi routeApi = new ProxyManager<>(RouteApi.class, gatewayUrl, okHttpClient).getInstance();
        ChatReqVO vo = new ChatReqVO(appConfiguration.getUserId(), "offLine");
        Response response = null;
        try {
            response = (Response) routeApi.offLine(vo);
        } catch (Exception e) {
            log.error("exception", e);
        } finally {
            response.body().close();
        }
    }
}
